var xlsx = require("node-xlsx");
var fs = require('fs');
var file_util = require('./public/file_util');
var path = require('path');
var coder = require('./public/coder')
var fileName = process.argv[2];

//if(fileName){
//var export_dir = "./";
//parseFile(fileName,export_dir);
//}
//表头列说明序号
const NAME = 0;
const VALUE = 0;

const LANG = 2;
const TEMPLATE = 1;
const DATA = 0;

// console.log(" fileName ",fileName);
var enums = "";
//语言表内容
var langObj = {};
// 索引表的内容


//每个key对应的索引值
var indexOfKey = {}
var template_c = ''
var template_s = ''
var template_s_data = ''
//解析Excel
function praseExcel(list, export_dir, type) {
	if (list.length <= 0) {
		return;
	}
	console.log("list.length ", list.length);

	var lang_path = path.join(export_dir, 'lang')
	var json_path = path.join(export_dir, 'json')
	//var ts_path = path.join(export_dir,'ts')
	var class_path = path.join(export_dir, 'class')
	//合并文件
	var bigObj = {};
	bigObj["data"] = {};
	var headConfig = list[0].data;
	console.log(" headconfig ", headConfig);
	var head_info_type = headConfig[0][1];
	console.log(" head_info_type ", head_info_type);

	if(type == "c"){
		if(head_info_type == "S"){
			return;
		}
	}
	else if(type == "s"){
		if(head_info_type == "C"){
			return;
		}
	}

	var head_info_type_arr =[];
	for(var i = 1; i < headConfig.length; i ++){
		head_info_type_arr[i] = headConfig[i][1];
		console.log(" head_info_type_arr[",i,"] ", head_info_type_arr[i]);
	}

	var bigFileName = headConfig[NAME][VALUE];
	console.log("name is ", NAME, " value ", VALUE, " bigFileName ", bigFileName);
	for (var i = 1; i < list.length; i++) {
		if (!headConfig[i]) {
			continue;
		}
		if(type == "c"){
			if(head_info_type_arr[i] == "S"){
			    continue;
            }
        }
        else if(type == "s"){
            if(head_info_type_arr[i] == "C"){
            	continue;
            }
        }

		//console.log('list[i] ',list[i])
		langObj = {};
		var indexObj = {};
		var result = {}; //每张表的导出内容
		var keys = {}; // id列表，对应内容的索引。
		var excleData = list[i].data;
		var dataArray = [];
		var nameArray = excleData[0]; // 第一行 说明
		var keyArray = excleData[1]; //第二行 名称
		var typeArray = excleData[2]; // 第三行 类型
		var scArray = excleData[3]; // 第四行 导出类别 s 服务器  c 客户端 sc 服务器与客户端。
		var index = 0;

		

		var sheetName = headConfig[i][VALUE];
		console.log(" i ", i, " sheetname", sheetName);
		var enumName = sheetName.substring(0, 1).toUpperCase() + sheetName.substring(1);

		var enumObj = "export enum " + enumName + "Enum{\n\t%{data}\n}";
		var enums = "";
		var keyIndex = 0;
		for (var k = 1; k < keyArray.length; k++) {
			if (typeArray[k] != 'null') {
			    if(type == "c"){
			        if(scArray[k] == "S"){
			            continue;
                	}
                }
                else if(type == "s"){
                	if(scArray[k] == "C"){
                		continue;
                    }
                }

				var key = keyArray[k];
				enums += key + ",// " + nameArray[k] + "\n\t";
				indexOfKey[key] = keyIndex++
			}
		}

		enumObj = enumObj.replace('%{data}', enums);

		for (var j = 4; j < excleData.length; j++) {
			var curData = excleData[j];
			if (curData.length == 0) continue;
			var item = changeObj(sheetName, curData, typeArray, keyArray, scArray, indexObj, type);
			keys[curData[0]] = index;
			index++;
			dataArray.push(item);
		}
		// index = 0;
		console.log('enumObj ', enumObj)

        if(type == "c"){
            if (dataArray.length > 0) {
        			exportClass_c(class_path, enumName, keyArray, typeArray, nameArray, list[i].name, enumObj, scArray)
        			result["data"] = dataArray;
        			result["key"] = keys;
        			result["type"] = DATA;
        			if (indexObj) {
        				result["index"] = indexObj;
        			}
        			// console.log("list[i].name",sheetName);
        			if (!bigFileName || bigFileName == "null") { //如果不合并 直接导出
        				var filename = path.join(json_path, sheetName + ".txt");
        				file_util.writeFile(filename, JSON.stringify(coder.pack(result, 1)));
        			} else {
        				bigObj["data"][sheetName] = result;
        			}
        			if (langObj) {
        				file_util.writeFile(path.join(lang_path, sheetName + "_lang.txt"), JSON.stringify(langObj));
        			}
        		} else {
        			console.log("内容为null ");
        			console.log(' export file name ', json_path + sheetName + ".txt")
        		}
        }
        else{
            if (dataArray.length > 0) {
        			exportClass_s(class_path, enumName, keyArray, typeArray, nameArray, list[i].name, enumObj, scArray)
        			result["data"] = dataArray;
        			result["key"] = keys;
        			result["type"] = DATA;
        			if (indexObj) {
        				result["index"] = indexObj;
        			}
        			// console.log("list[i].name",sheetName);
        			if (!bigFileName || bigFileName == "null") { //如果不合并 直接导出
        				var filename = path.join(json_path, sheetName + ".txt");
        				file_util.writeFile(filename, JSON.stringify(coder.pack(result, 1)));
        			} else {
        				bigObj["data"][sheetName] = result;
        			}
        			if (langObj) {
        				file_util.writeFile(path.join(lang_path, sheetName + "_lang.txt"), JSON.stringify(langObj));
        			}
        		} else {
        			console.log("内容为null ");
        			console.log(' export file name ', json_path + sheetName + ".txt")
        		}
        }




	}
	if (bigFileName && bigFileName != "null") {
		var filename = path.join(json_path, bigFileName + ".txt");
		bigObj["type"] = TEMPLATE;
		let out = coder.pack(bigObj, 1)
		file_util.writeFile(filename, JSON.stringify(out));
	}
	console.log("qqq");
}

function exportClass_c(class_path, enumName, keyArray, typeArray, nameArray, sheetName, enumObj, scArray) {
	console.log(' class_path ',class_path)
	file_util.createDir(class_path)
	let className = enumName
	let classProtoName = className.split('_')[0] + "Proto"
	let classObj = template_c.replace('%ClassName%', className)
	classObj = classObj.replace('%ClassName%', className)
	classObj = classObj.replace('%ClassName%', className)
	classObj = classObj.replace('%dataName%', className.toLowerCase())
	classObj = classObj.replace('%SheetName%', sheetName)
	classObj = classObj.replace('%ClassProtoName%', classProtoName)
	classObj = classObj.replace('%ClassProtoName%', classProtoName)
	classObj = classObj.replace('%ClassProtoName%', classProtoName)
	classObj = classObj.replace('%ClassProtoName%', classProtoName)

  	let paramStr = ''
    	for (var k = 1; k < keyArray.length; k++) {
    	    if (typeArray[k] != 'null') {
	        if(scArray[k] == "S"){
                            continue;
                        }
	        var key = "// " + nameArray[k] + "\n\t"; //说明
    	        let funcName = keyArray[k].substring(0, 1).toLowerCase() + keyArray[k].substring(1);
    	        let typeName = typeArray[k].replace('[[[i]]]', "i[][][]");
                        typeName = typeName.replace('[[[f]]]', "f[][][]");
                        typeName = typeName.replace('[[[s]]]', "s[][][]");
                        typeName = typeName.replace('[[[l]]]', "l[][][]");
                        typeName = typeName.replace('[[i]]', "i[][]");
                        typeName = typeName.replace('[[f]]', "f[][]");
                        typeName = typeName.replace('[[s]]', "s[][]");
                        typeName = typeName.replace('[[l]]', "l[][]");
                        typeName = typeName.replace('[i]', "i[]");
                        typeName = typeName.replace('[f]', "f[]");
                        typeName = typeName.replace('[s]', "s[]");
                        typeName = typeName.replace('[l]', "l[]");
                        typeName = typeName.replace('i', "EncryptInt");
                        typeName = typeName.replace('l', "EncryptLong");
                        typeName = typeName.replace('f', "EncryptFloat");
                        typeName = typeName.replace('s', "string");
                        typeName = typeName.replace('lang', "string");
    	        key += 'private ' +typeName+" "+ funcName + ";\n\t";
    	        paramStr += key;
    	    }
    	}
    	classObj = classObj.replace('%param%', paramStr)


   	let pfStr = ''
    	var kIndex = 0;
    	for (var k = 1; k < keyArray.length; k++) {
        	if (typeArray[k] != 'null') {
	        if(scArray[k] == "S"){
				continue;
            }

	        var key = "";
	        let funcName = keyArray[k].substring(0, 1).toLowerCase() + keyArray[k].substring(1);
	        let funcNameM = keyArray[k].substring(0, 1).toLowerCase() + keyArray[k].substring(1);
	        if(typeArray[k] == "i"){
	            key += 'this.' +funcName+" = (EncryptInt)data["+kIndex + "].n;\n\t\t";
	        }
	        else if(typeArray[k] == "l"){
	            key += 'this.' +funcName+" = (EncryptLong)data["+kIndex + "].n;\n\t\t";
	        }
	        else if(typeArray[k] == "lang"){
				key += 'this.' +funcName+" = data["+kIndex + "].str;\n\t\t";
            }
	        else if(typeArray[k] == "f"){
	            key += 'this.' +funcName+" = data["+kIndex + "].f;\n\t\t";
	        }
			else if(typeArray[k] == "s"){
	            key += 'this.' +funcName+" = data["+kIndex + "].str;\n\t\t";
	        }
	        else{
				key += 'this.' +funcName+" = ("+ typeArray[k]  +")data["+kIndex + "];\n\t\t";
	        }

	        pfStr += key;
	        kIndex ++;
	    }
     }
    	classObj = classObj.replace('%p=f%', pfStr)

  	let functionStr = ''
        	for (var k = 1; k < keyArray.length; k++) {
        	    if (typeArray[k] != 'null') {
	        if(scArray[k] == "S"){
                           continue;
                        }

	        var key = "// " + nameArray[k] + "\n\t"; //说明
	        let funcName = keyArray[k].substring(0, 1).toUpperCase() + keyArray[k].substring(1);
	        let funcNameM = keyArray[k].substring(0, 1).toLowerCase() + keyArray[k].substring(1);
	       if(typeArray[k] == "lang"){
		key += 'public string' +" Get"+ funcName + "(){\n\t\t";
	        	key += 'return LangManager.Instance.GetLocalString( ' + funcNameM + ");\n\t";
	        	key += "}\n\t";
	       }
	       else{
	        let typeName = typeArray[k].replace('[[[i]]]', "i[][][]");
                        typeName = typeName.replace('[[[f]]]', "f[][][]");
                        typeName = typeName.replace('[[[s]]]', "s[][][]");
                        typeName = typeName.replace('[[[l]]]', "l[][][]");
                        typeName = typeName.replace('[[i]]', "i[][]");
                        typeName = typeName.replace('[[f]]', "f[][]");
                        typeName = typeName.replace('[[s]]', "s[][]");
                        typeName = typeName.replace('[[l]]', "l[][]");
                        typeName = typeName.replace('[i]', "i[]");
                        typeName = typeName.replace('[f]', "f[]");
                        typeName = typeName.replace('[s]', "s[]");
                        typeName = typeName.replace('[l]', "l[]");
                        typeName = typeName.replace('l', "EncryptLong");
                        typeName = typeName.replace('i', "EncryptInt");
                        typeName = typeName.replace('f', "EncryptFloat");
                        typeName = typeName.replace('s', "string");
                        typeName = typeName.replace('lang', "string");
 	        key += 'public ' +typeName+" Get"+ funcName + "(){\n\t\t";
	        key += 'return ' + funcNameM + ";\n\t";
	        key += "}\n\t";
	       }
	       
	        functionStr += key;
	    }
        	}

        	classObj = classObj.replace('%function%', functionStr)

	file_util.writeFile(path.join(class_path, classProtoName + ".cs"), classObj);
}


function exportClass_s(class_path, enumName, keyArray, typeArray, nameArray, sheetName, enumObj, scArray) {
	console.log(' class_path ',class_path)
	file_util.createDir(class_path+"/protodata")
	file_util.createDir(class_path+"/proto")
	let className = enumName
	let classProtoName = className.split('_')[0] + "Proto"
	let classObj = template_s.replace('%ClassName%', className)
	classObj = classObj.replace('%ClassName%', className)
	classObj = classObj.replace('%ClassName%', className)
	classObj = classObj.replace('%SheetName%', sheetName)
	classObj = classObj.replace('%ClassProtoName%', classProtoName)
	classObj = classObj.replace('%ClassProtoName%', classProtoName)
	classObj = classObj.replace('%ClassProtoName%', classProtoName)
	classObj = classObj.replace('%ClassProtoName%', classProtoName)
	file_util.writeFile(path.join(class_path+"/proto", classProtoName + ".java"), classObj);

	let classData = template_s_data.replace('%ClassName%', className)
    	classData = classData.replace('%dataName%', className.toLowerCase())
    	classData = classData.replace('%SheetName%', sheetName)

    let paramStr = ''
    for (var k = 1; k < keyArray.length; k++) {
    		if (typeArray[k] != 'null') {

    		    if(scArray[k] == "C"){
                    continue;
                }

    			var key = "// " + nameArray[k] + "\n\t"; //说明
    			let funcName = keyArray[k].substring(0, 1).toLowerCase() + keyArray[k].substring(1);
    			let typeName = typeArray[k].replace('[[[i]]]', "i[][][]");
                    typeName = typeName.replace('[[[f]]]', "f[][][]");
                    typeName = typeName.replace('[[[s]]]', "s[][][]");
                    typeName = typeName.replace('[[[l]]]', "l[][][]");
                    typeName = typeName.replace('[[i]]', "i[][]");
                    typeName = typeName.replace('[[f]]', "f[][]");
                    typeName = typeName.replace('[[s]]', "s[][]");
                    typeName = typeName.replace('[[l]]', "l[][]");
                    typeName = typeName.replace('[i]', "i[]");
                    typeName = typeName.replace('[f]', "f[]");
                    typeName = typeName.replace('[s]', "s[]");
                    typeName = typeName.replace('[l]', "l[]");
                    typeName = typeName.replace('i', "int");
                    typeName = typeName.replace('l', "long");
                    typeName = typeName.replace('f', "float");
                    typeName = typeName.replace('s', "String");
                    typeName = typeName.replace('lang', "String");
    			key += 'private ' +typeName+" "+ funcName + ";\n\t";
    			paramStr += key;
    		}
    	}

    classData = classData.replace('%param%', paramStr)

    let pfStr = ''
    var kIndex = 0;
    for (var k = 1; k < keyArray.length; k++) {
        		if (typeArray[k] != 'null') {

        		    if(scArray[k] == "C"){
                        continue;
                    }

        			var key = "";
        			let funcName = keyArray[k].substring(0, 1).toLowerCase() + keyArray[k].substring(1);
        			let funcNameM = keyArray[k].substring(0, 1).toLowerCase() + keyArray[k].substring(1);
        			if(typeArray[k] == "i"){
        			    key += 'this.' +funcName+" = (int) data["+kIndex + "];\n\t\t";
        			}
        			else if(typeArray[k] == "l"){
        			    key += 'this.' +funcName+" = (long) data["+kIndex + "];\n\t\t";
        			}
        			else if(typeArray[k] == "lang"){
                        key += 'this.' +funcName+" = data["+kIndex + "].toString();\n\t\t";
                    }
        			else if(typeArray[k] == "f"){
        			    key += 'this.' +funcName+" = Float.parseFloat(data["+kIndex + "].toString());\n\t\t";
                    }
                    else{
                        key += 'this.' +funcName+" = ("+ typeArray[k]  +")data["+kIndex + "];\n\t\t";
                    }

        			pfStr += key;
        			kIndex ++;
        		}
        	}
    classData = classData.replace('%p=f%', pfStr)

    let functionStr = ''
        for (var k = 1; k < keyArray.length; k++) {
        		if (typeArray[k] != 'null') {

        		    if(scArray[k] == "C"){
                        continue;
                    }

        			var key = "// " + nameArray[k] + "\n\t"; //说明
        			let funcName = keyArray[k].substring(0, 1).toUpperCase() + keyArray[k].substring(1);
        			let funcNameM = keyArray[k].substring(0, 1).toLowerCase() + keyArray[k].substring(1);
        			let typeName = typeArray[k].replace('[[[i]]]', "i[][][]");
                        typeName = typeName.replace('[[[f]]]', "f[][][]");
                        typeName = typeName.replace('[[[s]]]', "s[][][]");
                        typeName = typeName.replace('[[[l]]]', "l[][][]");
                        typeName = typeName.replace('[[i]]', "i[][]");
                        typeName = typeName.replace('[[f]]', "f[][]");
                        typeName = typeName.replace('[[s]]', "s[][]");
                        typeName = typeName.replace('[[l]]', "l[][]");
                        typeName = typeName.replace('[i]', "i[]");
                        typeName = typeName.replace('[f]', "f[]");
                        typeName = typeName.replace('[s]', "s[]");
                        typeName = typeName.replace('[l]', "l[]");
                        typeName = typeName.replace('i', "int");
                        typeName = typeName.replace('l', "long");
                        typeName = typeName.replace('f', "float");
                        typeName = typeName.replace('s', "String");
                        typeName = typeName.replace('lang', "String");
        			key += 'public ' +typeName+" Get"+ funcName + "(){\n\t\t";
        			key += 'return ' + funcNameM + ";\n\t";
        			key += "}\n\t";
        			functionStr += key;
        		}
        	}

        classData = classData.replace('%function%', functionStr)

    file_util.writeFile(path.join(class_path+"/protodata", className + ".java"), classData);
	/*
	let exportStr = ''
	for (var k = 1; k < keyArray.length; k++) {
		if (typeArray[k] != 'null') {

		    if(scArray[k] == "C"){
                continue;
            }

			var key = "// " + nameArray[k] + "\n\t"; //说明
			let funcName = keyArray[k].substring(0, 1).toUpperCase() + keyArray[k].substring(1);
			key += 'get' + funcName + "() {\n\t\t"; //getkeyArray[k](){
			key += 'return this.data[' + enumName + 'Enum.' + keyArray[k] + ']\n\t';
			key += '}\n\t'
			exportStr += key;
		}
	}
	classObj = classObj.replace('%function%', exportStr)
	*/
}

//转换数据类型
function changeObj(sheetName, curData, typeArray, keyArray, scArray, indexObj, type) {
	var id = curData[0];
	var obj = [];
	for (var i = 1; i < curData.length; i++) {
		// console.log("data "+curData[i]+" type "+typeArray[i]+" key "+keyArray[i]+" sc "+scArray[i]);
		//字母
		if(type == "c"){
		    if(scArray[i] == "S"){
		        continue;
		    }
		}
		else if(type == "s"){
		    if(scArray[i] == "C"){
		        continue;
            }
		}
		if (typeArray[i] != 'null') {
			obj.push(changeValue(curData[i], typeArray[i], sheetName, id, keyArray[i], i - 1, indexObj));
		}

	}
	return obj;
}

function changeValue(value, type, sheetName, id, key, index, indexObj) {

	//console.log(" type ",type," value ",value,' sheetName ',sheetName,' index ',index);
	var start = type.indexOf('[');
	if (start >= 0) {
		if (value == null || value == "null" || value == "") return [];
		value = "" + value;
		var end = type.indexOf(']', type.length - 1);
		var t = type.substring(start + 1, end);
		// console.log(" end ",end," start ",start," t ",t);
		if (type.indexOf('[[') >= 0) {
			var list1 = value.split('|');
			var temp1 = [];
			for (var i = 0; i < list1.length; i++) {
				temp1.push(changeValue(list1[i], t, sheetName, id, key, index));
			}
			return temp1;
		} else {
			var list2 = value.split(',');
			var temp2 = [];
			var t2 = type.substring(start + 1, end);
			for (var i = 0; i < list2.length; i++) {
				temp2.push(changeValue(list2[i], t2, sheetName, id, key));
			}
			return temp2;
		}
	} else {
		switch (type) {
			case 'n':
				if (value == null || value == "null") return 0;
				let v = new Number(value)
				return v
			case 'i':
				if (value == null || value == "null") return 0;
				return parseInt(value);
			case 'l':
				if (value == null || value == "null") return 0;
				return parseInt(value);
			case 'f':
				if (value == null || value == "null") return 0.0;
				return parseFloat(value);
			case 's':
				if (value == null || value == "null") return "";
				return value;
			case 'lang': // 根据文件名key 和列名 生成ID并返回生成的ID
				if (value == null || value == "null") return "";
				var langID = sheetName + "_" + key + "_" + id;
				langObj[langID] = value;
				return langID;
			case 'index':
				var idx = indexOfKey[key]
				if (!indexObj[idx]) {
					indexObj[idx] = {}
				}
				if (value >= 0) {
					if (!indexObj[idx][value]) {
						indexObj[idx][value] = []
					}
					//console.log("index  value ",value,' id ',id)
					indexObj[idx][value].push(id);
					return parseInt(value);
				}
				return 0;
			case 'any':
				return value;
			case 'null':
				return ""

		}

	}

	return "";
}

var ignoreFileList = ['脚本数据', 'test']
// 加密算法可以公开  
function encrypt(plainText, key) {
	return plainText ^ key;
}

// 解密算法也可以公开  
function decrypt(cipherText, key) {
	return cipherText ^ key;
}

function parseFile(fileName, exportPath, type) {
	console.log("parseFile  fileName ", fileName)
	for (var i = 0; i < ignoreFileList.length; i++) {
		if (fileName.indexOf(ignoreFileList[i]) >= 0) {
			return;
		}
	}
	praseExcel(xlsx.parse(fileName), exportPath, type);
}


function readDir_c(dir, exportPath) {
	
	console.log(' readDir ===================')
	var stat = fs.statSync(dir);
	if (!stat.isDirectory()) {
		return;
	}
	var subpaths = fs.readdirSync(dir),
		subpath;
	for (var i = 0; i < subpaths.length; ++i) {
		if (subpaths[i][0] === '.') {
			continue;
		}
		subpath = path.join(dir, subpaths[i]);
		console.log(' readDir   subpath ',subpath)
		stat = fs.statSync(subpath);
		if (stat.isDirectory()) {
			// readDir(subpath, obj);
		} else if (stat.isFile()) {
			// Size in Bytes
			// console.log(" subpath ",subpath);
			parseFile(subpath, exportPath, "c");
		}
	}
}

function readDir_s(dir, exportPath) {

	console.log(' readDir ===================')
	var stat = fs.statSync(dir);
	if (!stat.isDirectory()) {
		return;
	}
	var subpaths = fs.readdirSync(dir),
		subpath;
	for (var i = 0; i < subpaths.length; ++i) {
		if (subpaths[i][0] === '.') {
			continue;
		}
		subpath = path.join(dir, subpaths[i]);
		console.log(' readDir   subpath ',subpath)
		stat = fs.statSync(subpath);
		if (stat.isDirectory()) {
			// readDir(subpath, obj);
		} else if (stat.isFile()) {
			// Size in Bytes
			// console.log(" subpath ",subpath);
			parseFile(subpath, exportPath, "s");
		}
	}
}

function init(cur_path) {
	template_c = file_util.readFile(path.join(cur_path,'template','class_c.cs'));
	template_s = file_util.readFile(path.join(cur_path,'template','class_s.java'));
	template_s_data = file_util.readFile(path.join(cur_path,'template','class_s_data.java'));
}
var test = function() {
	Editor.log(" test ")
}

module.exports.test = test
module.exports.init = init
module.exports.readDir_c = readDir_c
module.exports.readDir_s = readDir_s